package com.caochenlei.codebuilder.config;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.caochenlei.codebuilder.main.CodeBuilder;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import com.caochenlei.codebuilder.entity.Column;
import com.caochenlei.codebuilder.entity.Database;
import com.caochenlei.codebuilder.entity.Table;
import com.caochenlei.codebuilder.utils.SystemUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DatabaseConfigUtil {
	private static Logger logger = LoggerFactory.getLogger(DatabaseConfigUtil.class);

	/**
	 * 功能说明：将数据库信息读入到对象
	 * 
	 * @param configName
	 * @return
	 */
	public static Database read(String configName) {
		try {
			SAXReader saxReader = new SAXReader();
			Document document = null;
			try {
				document = saxReader.read(new BufferedReader(new InputStreamReader(new FileInputStream(SystemUtil.getConfigAbsolutePathByName(configName)), "UTF-8")));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			Element rootElement = document.getRootElement();

			String dbIp = rootElement.attributeValue("dbIp");
			String dbPort = rootElement.attributeValue("dbPort");
			String dbName = rootElement.attributeValue("dbName");
			String dbUrl = rootElement.attributeValue("dbUrl");
			String dbUser = rootElement.attributeValue("dbUser");
			String dbPassword = rootElement.attributeValue("dbPassword");
			String dbType = rootElement.attributeValue("dbType");
			String dbDriverName = rootElement.attributeValue("dbDriverName");
			String dbDataSourceType = rootElement.attributeValue("dbDataSourceType");
			String dbDialect = rootElement.attributeValue("dbDialect");
			String dbGenerator = rootElement.attributeValue("dbGenerator");

			Database database = new Database();
			database.setDbIp(dbIp);
			database.setDbPort(dbPort);
			database.setDbName(dbName);
			database.setDbUrl(dbUrl);
			database.setDbUser(dbUser);
			database.setDbPassword(dbPassword);
			database.setDbType(dbType);
			database.setDbDriverName(dbDriverName);
			database.setDbDataSourceType(dbDataSourceType);
			database.setDbDialect(dbDialect);
			database.setDbGenerator(dbGenerator);

			List<Table> table_list = new ArrayList<Table>();
			List<?> tables = rootElement.elements();
			for (int i = 0; i < tables.size(); i++) {
				Element table = (Element) tables.get(i);
				Table _table_ = new Table();
				_table_.setTableName(table.attributeValue("tableName"));
				_table_.setTableComment(table.attributeValue("tableComment"));
				_table_.setTable1(table.attributeValue("table1"));
				_table_.setTable1Upper(table.attributeValue("Table1Upper"));
				_table_.setTable2(table.attributeValue("table2"));
				_table_.setTable2Upper(table.attributeValue("Table2Upper"));
				_table_.setTable3(table.attributeValue("table3"));
				_table_.setTable3Upper(table.attributeValue("Table3Upper"));

				_table_.setTablePrimaryKeyName(table.attributeValue("tablePrimaryKeyName"));
				_table_.setTablePrimaryKeyComment(table.attributeValue("tablePrimaryKeyComment"));
				_table_.setTablePrimaryKeyType(table.attributeValue("tablePrimaryKeyType"));
				_table_.setTablePrimaryKeyLanguageType(table.attributeValue("tablePrimaryKeyLanguageType"));
				_table_.setTablePrimary1(table.attributeValue("tablePrimary1"));
				_table_.setTablePrimary1Upper(table.attributeValue("TablePrimary1Upper"));
				_table_.setTablePrimary2(table.attributeValue("tablePrimary2"));
				_table_.setTablePrimary2Upper(table.attributeValue("TablePrimary2Upper"));
				_table_.setTablePrimary3(table.attributeValue("tablePrimary3"));
				_table_.setTablePrimary3Upper(table.attributeValue("TablePrimary3Upper"));

				List<Column> column_list = new ArrayList<Column>();
				List<?> columns = table.elements();
				for (int j = 0; j < columns.size(); j++) {
					Element column = (Element) columns.get(j);
					Column _column_ = new Column();
					_column_.setColumnName(column.attributeValue("columnName"));
					_column_.setColumnComment(column.attributeValue("columnComment"));
					_column_.setColumnType(column.attributeValue("columnType"));
					_column_.setColumnLanguageType(column.attributeValue("columnLanguageType"));
					_column_.setColumn1(column.attributeValue("column1"));
					_column_.setColumn1Upper(column.attributeValue("Column1Upper"));
					_column_.setColumn2(column.attributeValue("column2"));
					_column_.setColumn2Upper(column.attributeValue("Column2Upper"));
					_column_.setColumn3(column.attributeValue("column3"));
					_column_.setColumn3Upper(column.attributeValue("Column3Upper"));
					_column_.setIsPrimaryKey("true".equals(column.attributeValue("isPrimaryKey")));
					_column_.setIsUniqueKey("true".equals(column.attributeValue("isUniqueKey")));
					column_list.add(_column_);
				}
				_table_.setColumns(column_list);

				table_list.add(_table_);
			}
			database.setTables(table_list);

			return database;
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 功能说明：读取指定文档信息
	 * 
	 * @param filePath
	 * @return
	 */
	public static Database load(String filePath) {
		try {
			SAXReader saxReader = new SAXReader();
			Document document = null;
			try {
				document = saxReader.read(new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "UTF-8")));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			Element rootElement = document.getRootElement();

			String dbIp = rootElement.attributeValue("dbIp");
			String dbPort = rootElement.attributeValue("dbPort");
			String dbName = rootElement.attributeValue("dbName");
			String dbUrl = rootElement.attributeValue("dbUrl");
			String dbUser = rootElement.attributeValue("dbUser");
			String dbPassword = rootElement.attributeValue("dbPassword");
			String dbType = rootElement.attributeValue("dbType");
			String dbDriverName = rootElement.attributeValue("dbDriverName");
			String dbDataSourceType = rootElement.attributeValue("dbDataSourceType");
			String dbDialect = rootElement.attributeValue("dbDialect");
			String dbGenerator = rootElement.attributeValue("dbGenerator");

			Database database = new Database();
			database.setDbIp(dbIp);
			database.setDbPort(dbPort);
			database.setDbName(dbName);
			database.setDbUrl(dbUrl);
			database.setDbUser(dbUser);
			database.setDbPassword(dbPassword);
			database.setDbType(dbType);
			database.setDbDriverName(dbDriverName);
			database.setDbDataSourceType(dbDataSourceType);
			database.setDbDialect(dbDialect);
			database.setDbGenerator(dbGenerator);

			List<Table> table_list = new ArrayList<Table>();
			List<?> tables = rootElement.elements();
			for (int i = 0; i < tables.size(); i++) {
				Element table = (Element) tables.get(i);
				Table _table_ = new Table();
				_table_.setTableName(table.attributeValue("tableName"));
				_table_.setTableComment(table.attributeValue("tableComment"));
				_table_.setTable1(table.attributeValue("table1"));
				_table_.setTable1Upper(table.attributeValue("Table1Upper"));
				_table_.setTable2(table.attributeValue("table2"));
				_table_.setTable2Upper(table.attributeValue("Table2Upper"));
				_table_.setTable3(table.attributeValue("table3"));
				_table_.setTable3Upper(table.attributeValue("Table3Upper"));

				_table_.setTablePrimaryKeyName(table.attributeValue("tablePrimaryKeyName"));
				_table_.setTablePrimaryKeyComment(table.attributeValue("tablePrimaryKeyComment"));
				_table_.setTablePrimaryKeyType(table.attributeValue("tablePrimaryKeyType"));
				_table_.setTablePrimaryKeyLanguageType(table.attributeValue("tablePrimaryKeyLanguageType"));
				_table_.setTablePrimary1(table.attributeValue("tablePrimary1"));
				_table_.setTablePrimary1Upper(table.attributeValue("TablePrimary1Upper"));
				_table_.setTablePrimary2(table.attributeValue("tablePrimary2"));
				_table_.setTablePrimary2Upper(table.attributeValue("TablePrimary2Upper"));
				_table_.setTablePrimary3(table.attributeValue("tablePrimary3"));
				_table_.setTablePrimary3Upper(table.attributeValue("TablePrimary3Upper"));

				List<Column> column_list = new ArrayList<Column>();
				List<?> columns = table.elements();
				for (int j = 0; j < columns.size(); j++) {
					Element column = (Element) columns.get(j);
					Column _column_ = new Column();
					_column_.setColumnName(column.attributeValue("columnName"));
					_column_.setColumnComment(column.attributeValue("columnComment"));
					_column_.setColumnType(column.attributeValue("columnType"));
					_column_.setColumnLanguageType(column.attributeValue("columnLanguageType"));
					_column_.setColumn1(column.attributeValue("column1"));
					_column_.setColumn1Upper(column.attributeValue("Column1Upper"));
					_column_.setColumn2(column.attributeValue("column2"));
					_column_.setColumn2Upper(column.attributeValue("Column2Upper"));
					_column_.setColumn3(column.attributeValue("column3"));
					_column_.setColumn3Upper(column.attributeValue("Column3Upper"));
					_column_.setIsPrimaryKey("true".equals(column.attributeValue("isPrimaryKey")));
					_column_.setIsUniqueKey("true".equals(column.attributeValue("isUniqueKey")));
					column_list.add(_column_);
				}
				_table_.setColumns(column_list);

				table_list.add(_table_);
			}
			database.setTables(table_list);

			return database;
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 功能说明：将数据库信息写出到文件
	 * 
	 * @param map
	 */
	public static void write(String configName, Map<String, Database> map) {
		Document document = DocumentHelper.createDocument();
		document.setRootElement(DocumentHelper.createElement(configName));
		Element rootElement = document.getRootElement();

		Database database = map.get("database");
		rootElement.addAttribute("dbIp", database.getDbIp());
		rootElement.addAttribute("dbPort", database.getDbPort());
		rootElement.addAttribute("dbName", database.getDbName());
		rootElement.addAttribute("dbUrl", database.getDbUrl());
		rootElement.addAttribute("dbUser", database.getDbUser());
		rootElement.addAttribute("dbPassword", database.getDbPassword());
		rootElement.addAttribute("dbType", database.getDbType());
		rootElement.addAttribute("dbDriverName", database.getDbDriverName());
		rootElement.addAttribute("dbDataSourceType", database.getDbDataSourceType());
		rootElement.addAttribute("dbDialect", database.getDbDialect());
		rootElement.addAttribute("dbGenerator", database.getDbGenerator());

		List<Table> tables = database.getTables();
		for (Table table : tables) {
			Element _table_ = rootElement.addElement("table");
			_table_.addAttribute("tableName", table.getTableName());
			_table_.addAttribute("tableComment", table.getTableComment());
			_table_.addAttribute("table1", table.getTable1());
			_table_.addAttribute("Table1Upper", table.getTable1Upper());
			_table_.addAttribute("table2", table.getTable2());
			_table_.addAttribute("Table2Upper", table.getTable2Upper());
			_table_.addAttribute("table3", table.getTable3());
			_table_.addAttribute("Table3Upper", table.getTable3Upper());

			_table_.addAttribute("tablePrimaryKeyName", table.getTablePrimaryKeyName());
			_table_.addAttribute("tablePrimaryKeyComment", table.getTablePrimaryKeyComment());
			_table_.addAttribute("tablePrimaryKeyType", table.getTablePrimaryKeyType());
			_table_.addAttribute("tablePrimaryKeyLanguageType", table.getTablePrimaryKeyLanguageType());
			_table_.addAttribute("tablePrimary1", table.getTablePrimary1());
			_table_.addAttribute("TablePrimary1Upper", table.getTablePrimary1Upper());
			_table_.addAttribute("tablePrimary2", table.getTablePrimary2());
			_table_.addAttribute("TablePrimary2Upper", table.getTablePrimary2Upper());
			_table_.addAttribute("tablePrimary3", table.getTablePrimary3());
			_table_.addAttribute("TablePrimary3Upper", table.getTablePrimary3Upper());

			List<Column> columns = table.getColumns();
			for (Column column : columns) {
				Element _column_ = _table_.addElement("column");
				_column_.addAttribute("columnName", column.getColumnName());
				_column_.addAttribute("columnComment", column.getColumnComment());
				_column_.addAttribute("columnType", column.getColumnType());
				_column_.addAttribute("columnLanguageType", column.getColumnLanguageType());
				_column_.addAttribute("column1", column.getColumn1());
				_column_.addAttribute("Column1Upper", column.getColumn1Upper());
				_column_.addAttribute("column2", column.getColumn2());
				_column_.addAttribute("Column2Upper", column.getColumn2Upper());
				_column_.addAttribute("column3", column.getColumn3());
				_column_.addAttribute("Column3Upper", column.getColumn3Upper());
				_column_.addAttribute("isPrimaryKey", column.getIsPrimaryKey() + "");
				_column_.addAttribute("isUniqueKey", column.getIsUniqueKey() + "");
			}
		}

		FileWriter out = null;
		XMLWriter writer = null;
		try {
			out = new FileWriter(SystemUtil.getConfigAbsolutePathByName(configName));
			OutputFormat outputFormat = new OutputFormat();
			outputFormat.setEncoding("UTF-8");
			outputFormat.setNewlines(true);
			outputFormat.setNewLineAfterDeclaration(false);
			outputFormat.setIndent(true);
			outputFormat.setIndent("	");
			writer = new XMLWriter(out, outputFormat);
			writer.write(document);
		} catch (IOException e) {
			e.printStackTrace();
			logger.error("写入配置文件失败：" + e.getMessage());
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (writer != null) {
				try {
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
